package com.studyv3.test.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.util.DateUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.studyv3.common.core.domain.R;
import com.studyv3.common.core.domain.entity.SysUser;
import com.studyv3.system.mapper.SysUserMapper;
import com.studyv3.test.domain.*;
import com.studyv3.test.entity.PageResult;
import com.studyv3.test.entity.TodoQuery;
import com.studyv3.test.mapper.*;
import com.studyv3.test.service.WarehousService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author: 作者
 * @create: 2024-05-07 20:06
 * @Description:
 */
@Service
@RequiredArgsConstructor
public class WarehousServiceImpl implements WarehousService {
    @Resource
    ProductsMapper productsMapper;
    @Resource
    BatchMapper batchMapper;
    @Resource
    SysUserMapper sysUserMapper;
    @Resource
    private ApplyProductMapper applyProductMapper;
    @Resource
    private ApplyWasteMapper applyWasteMapper;

    @Resource
    private ApplyTakeMapper applyTakeMapper;

    @Override
    public R queryPageProductTodo(TodoQuery query) throws ParseException {
    // 条件构造
    LambdaQueryWrapper<ApplyProduct> wrapper = new LambdaQueryWrapper<>();
    wrapper.orderByAsc(ApplyProduct::getId);

    if (StringUtils.hasLength(query.getName())) {
        wrapper.like(ApplyProduct::getBatchName, query.getName());
    }
    if (StringUtils.hasLength(query.getApplicant())) {
        wrapper.like(ApplyProduct::getApplicant, query.getApplicant());
    }
    if (StringUtils.hasLength(query.getSdate())) {
        wrapper.ge(ApplyProduct::getCreateTime, DateUtils.parseDate(query.getSdate(), "yyyy-MM-dd"));
    }
    if (StringUtils.hasLength(query.getEdate())) {
        wrapper.le(ApplyProduct::getCreateTime, DateUtils.parseDate(query.getEdate(), "yyyy-MM-dd"));
    }
    wrapper.eq(ApplyProduct::getFlag, 1);

    // 分页查询
    Page<ApplyProduct> page = applyProductMapper.selectPage(new Page<>(query.getPage(), query.getSize()), wrapper);

    // 获取所有查询到的ApplyProduct的userIds,batchId和productsId
    List<Integer> applicants = page.getRecords().stream().map(ApplyProduct::getApplicant).distinct().collect(Collectors.toList());
    List<Integer> batchIds = page.getRecords().stream().map(ApplyProduct::getBatchId).distinct().collect(Collectors.toList());
    List<Integer> productIds = page.getRecords().stream().map(ApplyProduct::getProductsId).distinct().collect(Collectors.toList());

    // 查询user,Batch和Products信息
    Map<Long,String> a =sysUserMapper.selectList(Wrappers.<SysUser>query()
            .select("user_id","user_name")
            .in("user_id",applicants)).stream().collect(Collectors.toMap(SysUser::getUserId,SysUser::getUserName));
    Map<Integer,String> batchMap =batchMapper.selectList(Wrappers.<Batch>query()
            .select("id","name")
            .in("id",batchIds)).stream().collect(Collectors.toMap(Batch::getId,Batch::getName));
    Map<Integer,String> productsMap =productsMapper.selectList(Wrappers.<Products>query()
            .select("id","name")
            .in("id",productIds)).stream().collect(Collectors.toMap(Products::getId,Products::getName));

    // 填充名称信息
    page.getRecords().forEach(applyProduct -> {
        applyProduct.setApplicantName(a.getOrDefault((long)applyProduct.getApplicant(),""));
        applyProduct.setBatchName(batchMap.getOrDefault(applyProduct.getBatchId(), ""));
        applyProduct.setProductsName(productsMap.getOrDefault(applyProduct.getProductsId(), ""));
    });

    return R.ok(new PageResult<>(query.getPage(), query.getSize(), page.getTotal(), page.getRecords()));
}

    /**
     * 获取待处理的请求列表
     * @param batchId
     * @return
     */

    @Override
    public R getProductTodoByBatchId(Integer batchId){
        // 条件构造
        LambdaQueryWrapper<ApplyProduct> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByAsc(ApplyProduct::getId);
        wrapper.eq(ApplyProduct::getFlag, 2);
        wrapper.eq(ApplyProduct::getBatchId, batchId);

        // 分页查询
        List<ApplyProduct> listTodo = applyProductMapper.selectList(wrapper);
        if(ObjectUtil.isNotEmpty(listTodo)) {
            // 获取所有查询到的ApplyProduct的userIds,batchId和productsId
            List<Integer> applicants = listTodo.stream().map(ApplyProduct::getApplicant).distinct().collect(Collectors.toList());
            List<Integer> batchIds = listTodo.stream().map(ApplyProduct::getBatchId).distinct().collect(Collectors.toList());
            List<Integer> productIds = listTodo.stream().map(ApplyProduct::getProductsId).distinct().collect(Collectors.toList());


            // 查询user,Batch和Products信息
            Map<Long, String> a = sysUserMapper.selectList(Wrappers.<SysUser>query()
                    .select("user_id", "user_name")
                    .in("user_id", applicants)).stream().collect(Collectors.toMap(SysUser::getUserId, SysUser::getUserName));
            Map<Integer, String> batchMap = batchMapper.selectList(Wrappers.<Batch>query()
                    .select("id", "name")
                    .in("id", batchIds)).stream().collect(Collectors.toMap(Batch::getId, Batch::getName));
            Map<Integer, String> productsMap = productsMapper.selectList(Wrappers.<Products>query()
                    .select("id", "name")
                    .in("id", productIds)).stream().collect(Collectors.toMap(Products::getId, Products::getName));

            // 填充名称信息
            listTodo.forEach(applyProduct -> {
                applyProduct.setApplicantName(a.getOrDefault((long)applyProduct.getApplicant(), ""));
                applyProduct.setBatchName(batchMap.getOrDefault(applyProduct.getBatchId(), ""));
                applyProduct.setProductsName(productsMap.getOrDefault(applyProduct.getProductsId(), ""));
            });
        }
            return R.ok(listTodo);
    }
    /**
     * 获取已处理的请求列表
     * @param batchId
     * @return
     */

    @Override
    public R getProductCompleteByBatchId(Integer batchId){
        // 条件构造
        LambdaQueryWrapper<ApplyProduct> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByAsc(ApplyProduct::getId);
        wrapper.in(ApplyProduct::getFlag, Arrays.asList(0,1));
        wrapper.eq(ApplyProduct::getBatchId, batchId);

        // 分页查询
        List<ApplyProduct> list = applyProductMapper.selectList(wrapper);
        if(ObjectUtil.isNotEmpty(list)) {
            // 获取所有查询到的ApplyProduct的userIds,batchId和productsId
            List<Integer> applicants = list.stream().map(ApplyProduct::getApplicant).distinct().collect(Collectors.toList());
            List<Integer> batchIds = list.stream().map(ApplyProduct::getBatchId).distinct().collect(Collectors.toList());
            List<Integer> productIds = list.stream().map(ApplyProduct::getProductsId).distinct().collect(Collectors.toList());


            // 查询user,Batch和Products信息
            Map<Long, String> a = sysUserMapper.selectList(Wrappers.<SysUser>query()
                    .select("user_id", "user_name")
                    .in("user_id", applicants)).stream().collect(Collectors.toMap(SysUser::getUserId, SysUser::getUserName));
            Map<Integer, String> batchMap = batchMapper.selectList(Wrappers.<Batch>query()
                    .select("id", "name")
                    .in("id", batchIds)).stream().collect(Collectors.toMap(Batch::getId, Batch::getName));
            Map<Integer, String> productsMap = productsMapper.selectList(Wrappers.<Products>query()
                    .select("id", "name")
                    .in("id", productIds)).stream().collect(Collectors.toMap(Products::getId, Products::getName));

            // 填充名称信息
            list.forEach(applyProduct -> {
                applyProduct.setApplicantName(a.getOrDefault((long)applyProduct.getApplicant(), ""));
                applyProduct.setBatchName(batchMap.getOrDefault(applyProduct.getBatchId(), ""));
                applyProduct.setProductsName(productsMap.getOrDefault(applyProduct.getProductsId(), ""));
            });
        }
        return R.ok(list);
    }
    @Override
    public R agreeProduct(ApplyProduct applyProduct) {
        // 查询批次信息
        Batch batch = batchMapper.selectId(applyProduct.getBatchId());
        if (batch == null) {
            return R.fail("批次信息不存在");
        }

        // 计算该批次下所有产品的总价格，注意这里需要转换为BigDecimal进行精确计算
        BigDecimal totalProductPrice = applyProductMapper.sumPriceByBatchId(applyProduct.getBatchId());
        if (totalProductPrice == null) {
            totalProductPrice = BigDecimal.ZERO;
        }

        // 检查预算是否足够
        if (batch.getBudget().compareTo(totalProductPrice) < 0) {
            return R.fail("亲，该批次预算余额不足");
        }

        // 准备更新ApplyProduct的信息
        ApplyProduct updateInfo = new ApplyProduct();
        updateInfo.setId(applyProduct.getId());
        updateInfo.setFlag(1);
        updateInfo.setUpdateTime(LocalDateTime.now());

        // 执行更新操作
        boolean updateSuccess = applyProductMapper.updateById(updateInfo) > 0;

        return updateSuccess ? R.ok() : R.fail("亲，审核失败");
    }

    @Override
    public R disagreeProduct(Integer id) {
        // 参数校验
        if (id == null || id <= 0) {
            return R.fail("无效的申请ID");
        }

        // 使用ApplyProduct实体类来表示更新的状态变更
        ApplyProduct updateInfo = new ApplyProduct();
        updateInfo.setFlag(0); // 假设DISAGREE是枚举，代表驳回状态
        updateInfo.setUpdateTime(LocalDateTime.now());

        // 构建更新条件
        LambdaUpdateWrapper<ApplyProduct> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(ApplyProduct::getId, id);

        // 执行更新操作
        boolean updateSuccess = applyProductMapper.update(updateInfo, wrapper) > 0;

        return updateSuccess ? R.ok() : R.fail("亲，驳回失败");
    }

    @Override
    public R queryPageWasteTodo(TodoQuery query) throws ParseException {
        //条件
        LambdaQueryWrapper<ApplyWaste> wrapper=new LambdaQueryWrapper<>();
        wrapper.orderByAsc(ApplyWaste::getId);
        if(StringUtils.hasLength(query.getName())){
            wrapper.like(ApplyWaste::getObjectName,query.getName());
        }
        if(StringUtils.hasLength(query.getApplicant())){
            wrapper.like(ApplyWaste::getApplicant,query.getApplicant());
        }
        if(StringUtils.hasLength(query.getSdate())) {
            wrapper.ge(ApplyWaste::getCreateTime, DateUtils.parseDate(query.getSdate(), "yyyy-MM-dd"));
        }
        if(StringUtils.hasLength(query.getEdate())) {
            wrapper.le(ApplyWaste::getCreateTime, DateUtils.parseDate(query.getEdate(), "yyyy-MM-dd"));
        }
        wrapper.eq(ApplyWaste::getFlag,1);
        Page<ApplyWaste> page=applyWasteMapper.selectPage(new Page<ApplyWaste>(query.getPage(),query.getSize()),wrapper);
        return R.ok(new PageResult<ApplyWaste>(query.getPage(),query.getSize(),page.getTotal(),page.getRecords()));
    }


    @Override
    public R queryPageTakeTodo(TodoQuery query) throws ParseException {
        //条件
        LambdaQueryWrapper<ApplyTake> wrapper=new LambdaQueryWrapper<>();
        wrapper.orderByAsc(ApplyTake::getId);
//        if(StringUtils.hasLength(query.getName())){
//            wrapper.like(ApplyTake::getName,query.getName());
//        }
        if(StringUtils.hasLength(query.getApplicant())){
            wrapper.like(ApplyTake::getName,query.getApplicant());
        }
        if(StringUtils.hasLength(query.getSdate())) {
            wrapper.ge(ApplyTake::getCreateTime, DateUtils.parseDate(query.getSdate(), "yyyy-MM-dd"));
        }
        if(StringUtils.hasLength(query.getEdate())) {
            wrapper.le(ApplyTake::getCreateTime, DateUtils.parseDate(query.getEdate(), "yyyy-MM-dd"));
        }
        wrapper.eq(ApplyTake::getFlag,1);
        Page<ApplyTake> page=applyTakeMapper.selectPage(new Page<ApplyTake>(query.getPage(),query.getSize()),wrapper);
        return R.ok(new PageResult<ApplyTake>(query.getPage(),query.getSize(),page.getTotal(),page.getRecords()));
    }


}
